package com.shuo.mmap;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 使用FileChannel来读写文件
 */
public class FileChannelTest {

    public static void main(String[] args) throws Exception {
        new FileChannelTest().writeInts();
    }

    /**
     * 将100000个连续数写入文件中
     */
    private void writeInts() throws IOException {
        FileChannel fc = new FileOutputStream("testFileChannel.txt").getChannel();
        ByteBuffer buf = ByteBuffer.allocate(1024 * 1024);
        for (int i = 0; i < 100000; i++) {
            buf.putInt(i);
        }
        // 没有flip的话, 则data.txt最终全部为0, 因为读写指针指到了最后, 后面全是0; 而fc.write会调用buf的read
        // 可以debug观察buf.flip()前后buf.position的值变化情况
        buf.flip();
        fc.write(buf);
        fc.close();
    }

    private void baseOperation() throws IOException {
        // 获取通道，该通道允许写操作
        FileChannel fc = new FileOutputStream("data.txt").getChannel();
        // 将字节数组包装到缓冲区中
        fc.write(ByteBuffer.wrap("Some text".getBytes()));
        fc.close();

        // 随机读写文件流创建的管道
        fc = new RandomAccessFile("data.txt", "rw").getChannel();
        // fc.position()计算从文件的开始到当前位置之间的字节数
        System.out.println("此通道的文件位置：" + fc.position());
        // 设置此通道的文件位置,fc.size()此通道的文件的当前大小,该条语句执行后，通道位置处于文件的末尾
        fc.position(fc.size());
        // 在文件末尾写入字节
        fc.write(ByteBuffer.wrap("Some more".getBytes()));
        fc.close();

        // 用通道读取文件
        fc = new FileInputStream("data.txt").getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // 将文件内容读到指定的缓冲区中
        fc.read(buffer);
        buffer.flip();// 此行语句一定要有
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        fc.close();
    }
}
